package com.audaque.springboot.foshanupload.web.webdemo.controller;

import com.audaque.springboot.foshanupload.log.anno.WebLogAnno;
import com.audaque.springboot.foshanupload.web.anno.RAnno;
import com.audaque.springboot.foshanupload.web.webdemo.model.bo.TreeNodeBo;
import com.audaque.springboot.foshanupload.web.webdemo.service.impl.TreeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zgb
 * @desc ...
 * @date 2023-06-05 21:09:52
 */

@Slf4j
@RestController
@RequestMapping("tree")
public class TreeController {

    @Autowired
    private TreeService treeService;


    @RAnno
    @WebLogAnno
    @GetMapping("/check")
    public TreeNodeBo check() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        List<TreeNodeBo> list = new ArrayList<>();
        list.add(root);
        treeService.check(list, treeService.findNodeByLevel(3, root));
        return root;
    }


    @RAnno
    @WebLogAnno
    @PostMapping("/deleteById")
    public TreeNodeBo deleteById() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        treeService.deleteById(root, 3);
        return root;
    }


    @RAnno
    @WebLogAnno
    @GetMapping("/list2treeAndO2O")
    public List<TreeNodeBo> list2treeAndO2O() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        return treeService.list2treeAndO2O(treeService.tree2list(root), -1);
    }


    @RAnno
    @WebLogAnno
    @GetMapping("/tree2NoLeaf")
    public List<TreeNodeBo> tree2NoLeaf() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        return treeService.tree2NoLeaf(root);
    }

    @RAnno
    @WebLogAnno
    @GetMapping("/tree2leaf")
    public List<TreeNodeBo> tree2leaf() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        return treeService.tree2leaf(root);
    }


    @RAnno
    @WebLogAnno
    @GetMapping("/list2tree")
    public List<TreeNodeBo> list2tree() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        return treeService.list2tree(treeService.tree2list(root), -1);
    }


    @RAnno
    @WebLogAnno
    @GetMapping("/findNodeByLevel")
    public List<TreeNodeBo> findNodeByLevel() throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        return treeService.findNodeByLevel(3, root);
    }


    @RAnno
    @WebLogAnno
    @GetMapping("/findNodeById/{id}")
    public TreeNodeBo findNodeById(@PathVariable(value = "id") int id) throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        log.debug("root:" + root);//root:TreeController.TreeNodeBo(id=1, value=root, children=[TreeController.TreeNodeBo(id=2, value=node1, children=[TreeController.TreeNodeBo(id=4, value=node11, children=[TreeController.TreeNodeBo(id=8, value=node111, children=[])]), TreeController.TreeNodeBo(id=5, value=node12, children=[])]), TreeController.TreeNodeBo(id=3, value=node2, children=[TreeController.TreeNodeBo(id=6, value=node21, children=[]), TreeController.TreeNodeBo(id=7, value=node22, children=[])])])
        TreeNodeBo result = treeService.findNodeById(root, id);
        log.debug("result:" + result); //result:TreeController.TreeNodeBo(id=4, value=node11, children=[TreeController.TreeNodeBo(id=8, value=node111, children=[])])v
        return result;

    }

    @RAnno
    @WebLogAnno
    @GetMapping("/findPathToNode/{id}")
    public String findPathToNode(@PathVariable(value = "id") int id) throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        log.debug("root:" + root);//root:TreeController.TreeNodeBo(id=1, value=root, children=[TreeController.TreeNodeBo(id=2, value=node1, children=[TreeController.TreeNodeBo(id=4, value=node11, children=[TreeController.TreeNodeBo(id=8, value=node111, children=[])]), TreeController.TreeNodeBo(id=5, value=node12, children=[])]), TreeController.TreeNodeBo(id=3, value=node2, children=[TreeController.TreeNodeBo(id=6, value=node21, children=[]), TreeController.TreeNodeBo(id=7, value=node22, children=[])])])
        TreeNodeBo targetNode = treeService.findNodeById(root, id);

        List<TreeNodeBo> path = treeService.findPathToNode(root, targetNode);
        StringBuffer stringBuffer = new StringBuffer();

        for (TreeNodeBo node : path) {
            int id1 = node.getId();
            log.debug("id1:" + id1);
            stringBuffer.append(id1);
            stringBuffer.append("-");
        }

        String s = stringBuffer.toString();
        return s;

    }

    /**
     * 用chatgpt只能生成简单逻辑,所以这个方法需要人工拆分
     *
     * @param id
     * @throws Exception
     */
    @RAnno
    @WebLogAnno
    @GetMapping("/removeNodesExceptPathToNode/{id}")
    public void removeNodesExceptPathToNode(@PathVariable(value = "id") int id) throws Exception {
        TreeNodeBo root = TreeNodeBo.initTree();
        log.debug("root:" + root);//root:TreeController.TreeNodeBo(id=1, value=root, children=[TreeController.TreeNodeBo(id=2, value=node1, children=[TreeController.TreeNodeBo(id=4, value=node11, children=[TreeController.TreeNodeBo(id=8, value=node111, children=[])]), TreeController.TreeNodeBo(id=5, value=node12, children=[])]), TreeController.TreeNodeBo(id=3, value=node2, children=[TreeController.TreeNodeBo(id=6, value=node21, children=[]), TreeController.TreeNodeBo(id=7, value=node22, children=[])])])
        treeService.printTree(root, "");
        TreeNodeBo targetNode = treeService.findNodeById(root, id);
        List<TreeNodeBo> path = treeService.findPathToNode(root, targetNode);
        List<Integer> collect = new ArrayList<>();
        collect.addAll(path.stream().map(e -> e.getId()).collect(Collectors.toList()));
        TreeNodeBo one = treeService.findNodeById(root, id);
        collect.addAll(treeService.collectIds(one));
        List<Integer> collect1 = collect.stream().distinct().collect(Collectors.toList());
        log.debug("collect1:" + collect1);
        TreeNodeBo newRoot = treeService.createSubtree(collect1, root);
        log.debug("newRoot:" + newRoot);
        treeService.printTree(newRoot, "");
    }

    /**
     * java 打印树
     */
    //java 打印树
}
